package triangle;

import java.io.File;

/**
 * This file is part of Rodney Ryan's submission of
 * his solution to the "Triangle Puzzle".
 *
 * rodney@rodneyryan.com
 */
public class TrianglePuzzleSolver {

    private static final int DEFAULT_ALL_AT_ONCE_SIZE_LIMIT_MB = 30;

    public static void solve(String fileName) {
        main(new String[]{fileName});
    }

    public static void solve(String fileName, int allAtOnceSizeLimitMB) {
        main(new String[]{fileName, Integer.toString(allAtOnceSizeLimitMB)});
    }

    public static void main(String[] args) {

        String fileName = "????";
        int allAtOnceSizeLimitMB = -1;

        try {
            fileName = getFileName(args);
            allAtOnceSizeLimitMB = getAllAtOnceSizeLimitMB(args);

            System.setProperty("triangle.verbose", "true");
            System.out.println("Calculating maximal for triangle file \"" + fileName + "\".");

            long startTime = System.currentTimeMillis();

            TriangleMaximalCalculator triangleMaximalCalculator = new TriangleMaximalCalculator();
            Triangle triangle = new TriangleFile(fileName, allAtOnceSizeLimitMB);

            long maximalSum = triangleMaximalCalculator.calculate(triangle);
            System.out.format("Maximal sum is %,d", maximalSum);

            long elapsedTime = System.currentTimeMillis() - startTime;
            System.out.format(" (elapsed time %,d ms).%n", elapsedTime);

        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
            printUsage();

        } catch (OutOfMemoryError error) {
            System.out.println("\nError - out of memory reading file \"" + fileName + "\".");
            System.out.print("Specify a smaller \"all at once size limit MB\" value - ");
            System.out.print("current is " + allAtOnceSizeLimitMB + "MB - or");
            System.out.println(" increase the memory of the JVM.");
            System.out.flush();
        }
    }

    private static String getFileName(String[] args) {
        if (args.length == 0) {
            throw new IllegalArgumentException("Error - triangle file name missing.");
        }

        String fileName = args[0];
        File file = new File(fileName);
        if (!file.exists()) {
            throw new IllegalArgumentException("Error - file \"" + fileName + "\" could not be found.");
        }

        if (file.isDirectory()) {
            throw new IllegalArgumentException("Error - file \"" + fileName + "\" is a directory.");
        }

        return fileName;
    }

    private static int getAllAtOnceSizeLimitMB(String[] args) {
        int allAtOnceSizeLimitMB = DEFAULT_ALL_AT_ONCE_SIZE_LIMIT_MB;

        if (args.length > 1) {
            try {
                allAtOnceSizeLimitMB = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("Error - invalid \"all at once\" size limit - \"" + args[1] + "\"");
            }
        }

        return allAtOnceSizeLimitMB;
    }

    private static void printUsage() {
        System.out.println("\nUsage: java -jar TriangleSolver.jar <file name> <all at once size limit MB>");
        System.out.println("    <file name>");
        System.out.println("         The name of the file containing the triangle data.");
        System.out.println("    <all at once size limit MB> (optional parameter)");
        System.out.println("         Files over this size (in megabytes) will be read piece by piece.");
        System.out.println("         Default value is 30.");
        System.out.println();
        System.out.println("Example: java -jar TriangleSolver.jar triangle.txt");
        System.out.println("Example: java -jar TriangleSolver.jar data\\triangle.txt 64");
    }
}